<?xml-stylesheet type="text/xsl"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<xsl:output cdata-section-elements="script" method="html"/>
	<xsl:template match="/">
		<html>
			<head>
				<link rel="stylesheet" type="text/css" href="ppc.css"/>
				<script type="text/javascript">
				<![CDATA[
		var req;
		var values;
		var log_streams;

		function getDate (dateString)
		{
			var date = new Date ();
			
			// 2008-07-29 14:53:41
			// 012345678901234567890
			
			date.setFullYear (dateString.substring (0, 4));
			date.setMonth (dateString.substring (5, 7) - 1);
			date.setDate (dateString.substring (8, 10));
			date.setHours (dateString.substring (11, 13));
			date.setMinutes (dateString.substring (14, 16));
			date.setSeconds (dateString.substring (17, 19));
			
			return date;
		}
		
		
		function xmlLoaded()
		{
			if (req.readyState == 4) 
			{
				if (req.status == 200 || req.status == 0) 
				{
					var root = req.responseXML.documentElement;

					var generated = getDate (root.getAttribute ("generated"));

					var statistics = root.getElementsByTagName ("statistics");
					
					if (statistics != undefined)
					{
						var key_select = document.getElementById ("keys");
						
						var streams = statistics[0].getElementsByTagName ("stream");
						
						for (var i = 0; i < streams.length; i++)
						{
							var stream = streams[i].getAttribute ("name");

							var slices = streams[i].getElementsByTagName ("slice")

							if (slices.length > 0)
							{
								var option = document.createElement ("option");
								option.text = stream;
								option.value = stream;
						
								key_select.add (option, null); 
							
								var values_array = new Array ();
							
								for (var j = 0; j < slices.length; j++)
								{
									var slice = slices[j].getAttribute ("name");
									values_array.push (slice);
								}
							
								values[stream] = values_array;
							}
						}
					}
					
					var log = root.getElementsByTagName ("log");
					
					if (log != undefined)
					{
						log_streams = new Object ();

						var streams = log[0].getElementsByTagName ("stream");
						
						for (var i = 0; i < streams.length; i++)
						{
							var stream = streams[i].getAttribute ("name");

							var slices = streams[i].getElementsByTagName ("slice")
							
							if (slices.length > 0)
							{
								var values_array = new Array ();
							
								for (var j = 0; j < slices.length; j++)
								{
									
									var slice_object = new Object ();
									slice_object["name"] = slices[j].getAttribute ("name");
									slice_object["start"] = getDate (slices[j].getAttribute ("startDate"));
									
									if (slices[j].getAttribute ("endDate") != undefined)
										slice_object["end"] = getDate (slices[j].getAttribute ("endDate"));
									else 
										slice_object["end"] = generated;

									values_array.push (slice_object);
								}
							
								log_streams[stream] = values_array;
							}
						}
					}
				}
			}
		}

		function init (xml_path)
		{
			values = new Object ();

			req = new XMLHttpRequest ();
			
			req.onreadystatechange = xmlLoaded;
			req.open ("GET", xml_path, true);
			req.send ();
		}
		
		function updateValues ()
		{
			var key_select = document.getElementById ("keys");
			var values_select = document.getElementById ("values");
			
			var index = key_select.selectedIndex;
			
			var key = key_select.options[index];
			
			if (key.value != undefined)
			{
				var values_array = values[key.value];
				
				while (values_select.length > 0)
					values_select.remove (0);
				
				for (var i = 0; i < values_array.length; i++)
				{
					var value = values_array[i];
					
					var option = document.createElement ("option");
					option.text = value;
					option.value = value;
						
					values_select.add (option, null); 
				}
									
				updateReport ();
			}
		}

		function updateReport ()
		{
			var key_select = document.getElementById ("keys");
			var values_select = document.getElementById ("values");
			
			var index = key_select.selectedIndex;
			var key = key_select.options[index].value;

			index = values_select.selectedIndex;
			var value = values_select.options[index].value;
			
			var statistics = new Object ();
			
			var key_slices = log_streams[key];
			
			var test_slices = new Array ();

			
			var duration = 0;

			for (var i = 0; i < key_slices.length; i++)
			{
				if (key_slices[i]["name"] == value)
				{
					test_slices.push (key_slices[i]);
					
					duration += getOverlap (key_slices[i], key_slices[i]);
				}
			}
			
			for (var other_key in log_streams)
			{
				if (key != other_key)
				{
					var other_statistics = new Object ();

					var other_slices = log_streams[other_key];

					for (var j = 0; j < other_slices.length; j++)
					{
						var slice_stats = other_statistics[other_slices[j]["name"]];
						
						if (slice_stats == undefined)
						{
							slice_stats = new Object ();
							slice_stats["name"] = other_slices[j]["name"];
							slice_stats["elapsed"] = 0;
							slice_stats["frequency"] = 0;
							slice_stats["total_elapsed"] = 0;
							slice_stats["total_frequency"] = 0;
							
							other_statistics[other_slices[j]["name"]] = slice_stats;
						}

						for (var i = 0; i < test_slices.length; i++)
						{
							var overlap = getOverlap (test_slices[i], other_slices[j]);
							
							if (overlap > 0)
							{
								slice_stats["frequency"] += 1;
								slice_stats["elapsed"] += overlap;
							}
						}
						
						slice_stats["total_frequency"] += 1;
						slice_stats["total_elapsed"] += getOverlap (other_slices[j], other_slices[j]);
					}
					
					statistics[other_key] = other_statistics;
				}
			}
			
			renderStatistics (statistics, key, value, duration);
		}
		
		function getOverlap (a, b)
		{
			var a_start = a["start"].getTime ();
			var a_end = a["end"].getTime ();

			var b_start = b["start"].getTime ();
			var b_end = b["end"].getTime ();
			
			if ((a_start >= b_start && a_start <= b_end) || (a_end >= b_start && a_end <= b_end) ||
				(a_start <= b_start && a_end >= b_end))
			{
				var start = a_start;
				
				if (b_start > start)
					start = b_start;
					
				var end = a_end;
				
				if (b_end < end)
					end = b_end;
					
				return (end - start) / 1000;
			}
			
			return 0;
		}
		
		function renderStatistics (statistics, k, v, d)
		{
			var report_html = document.getElementById ("report_html");
			
			var text = "<p>" + k + " = " + v + " (" + d.toFixed (1) + "s elapsed)</p>";
		
			for (var key in statistics)
			{
				text += "<table><tr><td colspan=\"3\" class=\"stream-name\">" + key + "</td></tr>";
				
				var slices = statistics[key];
				
				var matches = new Array ();
				
				var overlap = false;
				
				for (var slice in slices)
				{
					if (slices[slice]["frequency"] > 0)
					{
						var match = new Object ();
						match["name"] = slice;
						match["count"] = slices[slice]["frequency"];
						match["duration"] = slices[slice]["elapsed"];
						
						matches.push (match);
					}
				}
				
				if (matches.length == 0)
					text += "<tr><td span=\"3\" class=\"name\">No slices overlapped within " + key + ".</td>";
				else
				{
					var sorted = matches.sort (sortMatches);
					
					for (var i = 0; i < sorted.length; i++)
					{
						text += "<tr><td class=\"name\">" + sorted[i]["name"] + "</td>";
						text += "<td class=\"count\">" + sorted[i]["count"] + "</td>";
						text += "<td class=\"duration\">" + sorted[i]["duration"].toFixed (1) + "</td></tr>";
					}
				}
			
				text += "</table>";
			}
			
			report_html.innerHTML = text;
		}
		
		function sortMatches (a, b)
		{
			return b["duration"] - a["duration"];
		}
				]]>
				</script>
			</head>
			<body onLoad="init ('ppc-report.xml')">
				<p class="title">Detailed Report</p>
				<div class="statistics">
					<p>Select a time stream and slice to view its correlation with other streams and slices.</p>

					<p>
						<select id="keys" onChange="updateValues ()">
							<option>Select a stream...</option>
						</select>
				
						is

						<select id="values" onChange="updateReport ()">
							<option>Select a value...</option>
						</select>
					</p>
					<div id="report_html" />
				</div>
			</body>
		</html>
	</xsl:template>

</xsl:stylesheet>